package cloud.seri.iot.manager.domain

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.DBRef
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.core.mapping.Field
import java.util.*
import javax.persistence.Entity
import javax.validation.constraints.NotNull
import javax.validation.constraints.Size

/**
 * 产品，设备分类.
 * @author A true Allen
 */
@Document(collection = "seri_product")
@Entity
class Product(
    /**
     * 产品Key
     */
    @Id
    var productKey: String? = null,

    /**
     * 产品名称
     */
    @get: NotNull
    @get: Size(min = 1, max = 32)
    @Field("product_name")
    var productName: String? = null,

    /**
     * 产品的数据类型，指设备与云端之间的数据通信协议类型。
     */
    @Field("data_format")
    var dataFormat: Int? = null,

    /**
     * 高级版产品的节点类型。取值：0：设备。设备不能挂载子设备，可以直连IoT Hub，也可以作为网关的子设备连接IoT Hub。1：网关。网关可以挂载子设备，具有子设备管理模块，维持子设备的拓扑关系，并且可以将拓扑关系同步到云端。
     */
    @Field("device_type")
    var deviceType: Int? = null,


    /**
     * 产品秘钥
     */
    @Field("product_secret")
    var productSecret: String? = null,

    /**
     * 设备类型
     */
    @Field("category_name")
    var categoryName: String? = null,

    /**
     * CategoryKey
     */
    @Field("category_key")
    var categoryKey: String? = null,

    /**
     * 联网方式
     */
    @Field("net_type")
    var netType: String? = null,

    /**
     * 状态
     */
    @Field("status")
    var status: Int? = null,

    /**
     * 产品描述
     */
    @Field("description")
    var description: String? = null,

    @DBRef(lazy = true)
    @Field("devices")
    var devices: MutableSet<Device> = mutableSetOf()

) : AbstractAuditingEntity()
{

    fun addDevices(device: Device): Product
    {
        this.devices.add(device)
        device.product = this
        return this
    }

    fun removeDevices(device: Device): Product
    {
        this.devices.remove(device)
        device.product = null
        return this
    }

    override fun equals(other: Any?): Boolean
    {
        if (this === other) return true
        if (other !is Product) return false

        return Objects.equals(productKey, other.productKey)
    }

    override fun hashCode(): Int
    {
        return 31
    }

    override fun toString(): String
    {
        return "Product{" +
            ", productName='$productName'" +
            ", dataFormat=$dataFormat" +
            ", deviceType=$deviceType" +
            ", productKey='$productKey'" +
            ", productSecret='$productSecret'" +
            ", categoryName='$categoryName'" +
            ", categoryKey='$categoryKey'" +
            ", netType='$netType'" +
            ", status=$status" +
            ", description='$description'" +
            "}"
    }

    companion object
    {
        private const val serialVersionUID = 1L
    }
}
